#include "Gateway.h"
#include <QCoreApplication>

Gateway::Gateway(QObject* parent)
    : QObject(parent)
{
    qApp->setApplicationName("gateway");
    qApp->setApplicationVersion("0.1-dev");
    QextLogger::setupMessageHandler();
    iostreamLogger = new IOStreamLogger(this);
    iostreamLogger->setFormat("%message");
    QextLogger::registerLogger(iostreamLogger);
    fileLogger = new FileLogger("./gateway.log", this);
    fileLogger->setFormat("%date at %time From %context: (%type) %message");
    QextLogger::registerLogger(fileLogger);

    xplService = NULL;
    zigbusConnection = NULL;
    translator = new ModuleMessageHandler(this);


}
//----------------------------------------------------------------
Gateway::~Gateway()
{
    xPLThread.quit();
    xPLThread.wait(); //wait until the end of execution
    zigbusThread.quit();
    zigbusThread.wait(); // wait until the end of execution
    if(translator != NULL) {
        delete translator;
    }
    QextLogger::releaseMessageHandler();
    if(iostreamLogger) {
        delete iostreamLogger;
        iostreamLogger = NULL;
    }
    if(fileLogger) {
        delete fileLogger;
        fileLogger = NULL;
    }
}
//----------------------------------------------------------------
void Gateway::init()
{
    qDebug() << "gateway init...";
    initializexPLService();
    //initializeZigbusConnection();
    emit start_xPLService(true);
}
//----------------------------------------------------------------
void Gateway::initializexPLService()
{
    xplService = new ZxPLService();
    xplService->moveToThread(&xPLThread);
    connect(&xPLThread, SIGNAL(finished()), xplService, SLOT(deleteLater()));
    connect(this, SIGNAL(start_xPLService(bool)), xplService, SLOT(listen(bool)));
    connect(this, SIGNAL(stop_xPLService()), xplService, SLOT(close()));
    connect(translator, SIGNAL(xPLMessageToSend(QxPLMessage)), xplService, SLOT(sendMessage(QxPLMessage)));
    connect(xplService, SIGNAL(moduleTargetedMessage(QxPLMessage)), translator, SLOT(processMessage(QxPLMessage)));
    connect(xplService, SIGNAL(configZigbusMediaRS232(QString,QString,QString,QString,QString,QString, bool)),
            this, SLOT(onConfigZMediaRS232(QString,QString,QString,QString,QString,QString, bool)));
    connect(xplService, SIGNAL(configZigbusMediaUdp(int, bool)), this, SLOT(onConfigMediaZUdp(int, bool)));
    xPLThread.start();
}
//----------------------------------------------------------------
void Gateway::initializeZigbusConnection()
{
    zigbusConnection = new UsbZigbusConnection("/dev/ttyUSB0");
    zigbusConnection->moveToThread(&zigbusThread);
    connect(&zigbusThread, SIGNAL(finished()), zigbusConnection, SLOT(deleteLater()));
    connect(this, SIGNAL(start_zigbusService()), zigbusConnection, SLOT(open()));
    connect(this, SIGNAL(stop_zigbusService()), zigbusConnection, SLOT(close()));
    connect(zigbusConnection, SIGNAL(messageReceived(ZigbusMessage)), translator, SLOT(processMessage(ZigbusMessage)));
    connect(translator, SIGNAL(zigbusMessageToSend(ZigbusMessage)), zigbusConnection, SLOT(sendMessage(ZigbusMessage)));
    zigbusThread.start();
}
//----------------------------------------------------------------
void Gateway::onConfigMediaZUdp(int port, bool enable)
{
    if(zigbusConnection) {
        qDebug() << "[zigbus] desactivating current connection...";
        zigbusThread.quit();
        zigbusThread.wait();
    }
    qDebug() << "[zigbus] loading new configuration connection: UDP("<<port<<")";
    zigbusConnection = new UDPZigbusConnection(port);
    zigbusConnection->moveToThread(&zigbusThread);
    connect(&zigbusThread, SIGNAL(finished()), zigbusConnection, SLOT(deleteLater()));
    connect(this, SIGNAL(start_zigbusService()), zigbusConnection, SLOT(open()));
    connect(this, SIGNAL(stop_zigbusService()), zigbusConnection, SLOT(close()));
    connect(zigbusConnection, SIGNAL(messageReceived(ZigbusMessage)), translator, SLOT(processMessage(ZigbusMessage)));
    connect(translator, SIGNAL(zigbusMessageToSend(ZigbusMessage)), zigbusConnection, SLOT(sendMessage(ZigbusMessage)));
    zigbusThread.start();
    if(enable) {
        qDebug() << "[zigbus] starting zigbus connection...";
        emit start_zigbusService();
    }
}
//----------------------------------------------------------------
void Gateway::onConfigZMediaRS232(QString port, QString baud, QString databit,
                         QString flow, QString parity, QString stopbit, bool enable)
{
    Q_UNUSED(port)
    Q_UNUSED(baud)
    Q_UNUSED(databit)
    Q_UNUSED(flow)
    Q_UNUSED(parity)
    Q_UNUSED(stopbit)
    Q_UNUSED(enable)
    if(zigbusConnection) {
        qDebug() << "[zigbus] desactivating current connection...";
        zigbusThread.quit();
        zigbusThread.wait();
    }
    qDebug() << "RS232 mode not implemented yet...";
    qDebug() << "zigbus desactivated";
}
//----------------------------------------------------------------
